package com.company.ljh.medium;
/**
 * 120.给定一个三角形 triangle ，找出自顶向下的最小路径和。
 *
 * 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说，如果正位于当前行的下标 i ，那么下一步可以移动到下一行的下标 i 或 i + 1 。
 *输入：triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
 * 输出：11
 * 解释：如下面简图所示：
 *    2
 *   3 4
 *  6 5 7
 * 4 1 8 3
 * 自顶向下的最小路径和为 11（即，2 + 3 + 5 + 1 = 11）。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/triangle
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/triangle
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

import java.util.List;

/**
 * @description:
 * @projectName:leet_code
 * @see:com.company.ljh.medium
 * @author:ljh
 * @createTime:2022/5/29 20:25
 * @version:1.0
 */
public class 三角形最小路径和 {
    public int minimumTotal(List<List<Integer>> triangle) {
        //dp[m][i] 走到第m层第i个结点的最小路径和
        //dp[m][i] = Math.min(dp[m-1][i]+nums[m][i],dp[m][i]+nums[m-1][i-1])
        //初始值 dp[0][0] = nums[0][0]
        //结果输出 dp[m][x]中最小的那个
        int dp[][]= new int[triangle.size()][triangle.size()];
        dp[0][0]= triangle.get(0).get(0);
        if(triangle.size() == 1){
            return dp[0][0];
        }
        int min = Integer.MAX_VALUE;
        for(int m =1;m < triangle.size();m++){
            List<Integer> list = triangle.get(m);
            for(int i =0;i<list.size();i++){
                if(i == 0 ){
                    dp[m][i] = dp[m-1][i]+list.get(i);
                }else if (i == m){
                    dp[m][i] = dp[m-1][i-1]+list.get(i);
                }else{
                    dp[m][i] = Math.min(dp[m-1][i]+list.get(i),dp[m-1][i-1]+list.get(i));
                }
                if(m == triangle.size()-1){
                    min = Math.min(min,dp[m][i]);
                }
            }

        }

        return min;

    }
}
